xui.Class("xui.APICaller", "xui.absObj", {
    Instance: {
        _ini: xui.Timer.prototype._ini,
        _after_ini: function (profile, ins, alias) {
            if (!profile.name) profile.Instace.setName(alias);
        },
        destroy: function () {
            this.each(function (profile) {
                var box = profile.box, name = profile.properties.name;
                //delete from pool
                delete box._pool[name];
                //free profile
                profile.__gc();
            });
        },
        setHost: function (value, alias) {
            var self = this;
            if (value && alias)
                self.setName(alias);
            return arguments.callee.upper.apply(self, arguments);
        },

        setQueryData: function (data, path) {
            return this.each(function (prf) {
                if (path) xui.set(prf.properties.queryArgs, (path || "").split("."), data);
                else prf.properties.queryArgs = data || {};
            });
        },


        invoke: function (onSuccess, onFail, onStart, onEnd, mode, threadid, options) {
            var ns = this, nns = ns,
                con = ns.constructor,
                prf = ns.get(0),
                prop = prf.properties;

            var responseType = prop.responseType,
                requestType = prop.requestType,
                requestId = prop.requestId,
                isAllform = prop.isAllform,
                queryURL = prop.queryURL,
                proxyType = prop.proxyType.toLowerCase(),
                queryUserName = prop.queryUserName,
                queryPasswrod = prop.queryPasswrod,
                queryArgs = xui.clone(prop.queryArgs),
                oAuth2Token = prop.oAuth2Token,
                queryOptions = xui.clone(prop.queryOptions),
                queryHeader = xui.clone(prop.queryHeader),
                requestDataSource = prop.requestDataSource,
                responseDataTarget = prop.responseDataTarget,
                responseCallback = prop.responseCallback,
                funs = xui.$cache.functions,
                t1 = funs['$APICaller:beforeInvoke'],
                t2 = funs['$APICaller:beforeData'],
                t3 = funs['$APICaller:onError'];

            queryURL = xui.adjustVar(queryURL);

            if (proxyType == "sajax") proxyType = "jsonp";
            else if (proxyType == "iajax") proxyType = "xdmi";
            if (requestType == "FORM" || requestType == "JSON") queryArgs = typeof queryArgs == 'string' ? xui.unserialize(queryArgs) : queryArgs;
            if (!queryArgs) queryArgs = {};
            if (prop.avoidCache) {
                var i = 0, rnd = "_rand_";
                while (queryArgs.hasOwnProperty(rnd)) rnd = "_rand_" + ++i;
                queryArgs[rnd] = xui.rand();
            }
            queryArgs['_currClassName_'] = prf.host.key;
            // merge request data
            if (requestDataSource && requestDataSource.length) {

                for (var i in requestDataSource) {
                    var o = requestDataSource[i], t, v, path;
                    switch (o.type) {
                        case "form":
                            if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.absContainer']) {
                                if (!prop.autoRun && (!t.checkValid() || !t.checkRequired())) {
                                    return;
                                } else {
                                    if (isAllform) {
                                        path = (o.path || "").split('.');

                                        if (xui.isHash(v = xui.get(queryArgs, path))) {
                                            if (o.name == 'pagectx') {
                                                xui.merge(v, t.getFormValues())
                                            } else {
                                                xui.merge(v, t.getAllFormValues(), 'all');
                                            }
                                        } else {
                                            xui.set(queryArgs, path, t.getAllFormValues());
                                        }

                                    } else {
                                        path = (o.path || "").split('.');
                                        if (xui.isHash(v = xui.get(queryArgs, path))) {
                                            if (o.name == 'pagectx') {
                                                xui.merge(v, t.getFormValues())
                                            } else {
                                                xui.merge(v, t.getFormValues(), 'all')
                                            }
                                        } else {
                                            xui.set(queryArgs, path, t.getFormValues());
                                        }
                                    }

                                }
                            }
                            break;
                    }
                }

                for (var i in requestDataSource) {
                    var o = requestDataSource[i], t, v, path;
                    switch (o.type) {
                        case "databinder":
                            if (t = xui.DataBinder.getFromName(o.name)) {
                                if (!t.updateDataFromUI()) {
                                    return;
                                } else {
                                    path = (o.path || "").split('.');
                                    if (xui.isHash(v = xui.get(queryArgs, path))) xui.merge(v, t.getData(), 'all');
                                    else xui.set(queryArgs, path, t.getData());
                                }
                            }
                            break;

                        case "spa":
                            if (window['SPA']) {
                                xui.set(queryArgs, o.path, SPA[o.name]);
                            }
                            break;
                        case "rad":
                            if (window['SPA']) {
                                switch (o.name) {
                                    case 'select':
                                        var items = SPA.getSelected();
                                        var itemids = [];
                                        xui.each(items, function (item) {
                                            itemids.push(item.alias);
                                        });
                                        xui.set(queryArgs, o.path, itemids);
                                        break;
                                }

                            }
                            break;

                        case "treeview":
                            if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.TreeView'] /*&& t.getRootNode()*/) {
                                path = (o.path || "id").split('.');
                                if (!t.getUIValue() || t.getUIValue() == '') {
                                    if (t.getSelectedItem()) {
                                        xui.set(queryArgs, path, t.getSelectedItem().id);
                                    }
                                } else {
                                    xui.set(queryArgs, path, t.getUIValue());
                                }

                                if (t.getSelectedItem() && t.getSelectedItem().tagVar) {
                                    xui.merge(queryArgs, t.getSelectedItem().tagVar, 'all');

                                }
                            }
                            break;

                        case "gallery":
                            if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.Gallery'] /*&& t.getRootNode()*/) {
                                path = (o.path || "id").split('.');
                                if (!t.getUIValue() || t.getUIValue() == '') {
                                    if (t.getSelectedItem()) {
                                        xui.set(queryArgs, path, t.getSelectedItem().id);

                                    }
                                } else {
                                    xui.set(queryArgs, path, t.getUIValue());
                                }
                                if (t.getSelectedItem() && t.getSelectedItem().tagVar) {
                                    xui.merge(queryArgs, t.getSelectedItem().tagVar, 'all');
                                }

                            }
                            break;


                        case "treegrid":
                            if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.TreeGrid'] /*&& t.getRootNode()*/) {
                                path = (o.path || (t.getUidColumn() && t.getUidColumn())).split('.');
                                if (!t.getUIValue() || t.getUIValue() == '') {
                                    if (t.getActiveRow('map')) {
                                        xui.set(queryArgs, path, t.getActiveRow('map')[t.getUidColumn()]);
                                    }
                                } else {
                                    xui.set(queryArgs, path, t.getUIValue());
                                }
                            }
                            break;

                        case "treegridrow":
                            if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.TreeGrid'] /*&& t.getRootNode()*/) {
                                path = (o.path || (t.getUidColumn() && t.getUidColumn())).split('.');
                                if (t.getActiveRow('map')) {
                                    xui.set(queryArgs, path, t.getActiveRow('map')[t.getUidColumn()]);
                                }
                            }
                            break;

                        case "pagebar":
                            if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.PageBar'] /*&& t.getRootNode()*/) {
                                var pageparams = {
                                    pageSize: t.getPageCount(),
                                    pageIndex: t.getPage()
                                };
                                if (xui.isHash(v = xui.get(queryArgs, path))) xui.merge(v, pageparams, 'all');
                                else xui.set(queryArgs, path, pageparams);
                            }
                            break;
                    }
                }
            }
            // the global handler
            if (xui.isFun(t1) && false === t1(requestId, prf))
                return;
            else if (xui.isHash(t1) && xui.isArr(t1.actions)
                && false === xui.pseudocode._callFunctions(t1, [requestId, prf], ns.getHost(), null, null, '$APICaller:beforeInvoke')
            )
                return;
            // Normally, Gives a change to modify "queryArgs" for XML
            if (prf.beforeInvoke && false === prf.boxing().beforeInvoke(prf, requestId))
                return;

            // for auto adjusting options
            var rMap = {header: {}};
            if (!xui.isEmpty(queryHeader)) {
                xui.merge(rMap.header, queryHeader);
            }
            if (queryOptions.header && !xui.isEmpty(queryOptions.header)) {
                xui.merge(rMap.header, queryOptions.header);
                delete queryOptions.header;
            }
            if (responseType == 'SOAP' || requestType == 'SOAP') {
                // for wsdl
                if (!con.WDSLCache) con.WDSLCache = {};
                if (!con.WDSLCache[queryURL]) {
                    var wsdl = xui.SOAP.getWsdl(queryURL, function (rspData) {
                        if (prf.afterInvoke) prf.boxing().afterInvoke(prf, rspData, requestId);

                        // the global handler
                        if (xui.isFun(t3)) t3(rspData, requestId, prf);
                        else if (xui.isHash(t3) && xui.isArr(t3.actions)) xui.pseudocode._callFunctions(t3, [rspData, requestId, prf], ns.getHost(), null, null, '$APICaller:onError');

                        if (prf.onError) prf.boxing().onError(prf, rspData, requestId);
                        xui.tryF(onFail, arguments, this);
                        xui.tryF(onEnd, arguments, this);
                    });
                    if (wsdl)
                        con.WDSLCache[queryURL] = wsdl;
                    else
                    // stop the further call
                        return;
                }
            }
            switch (responseType) {
                case "TEXT":
                    rMap.rspType = "text";
                case "JSON":
                    rMap.rspType = "json";
                    break;
                case "XML":
                    proxyType = "ajax";
                    rMap.rspType = "xml";
                    break;
                case "SOAP":
                    proxyType = "ajax";
                    rMap.rspType = "xml";
                    var namespace = xui.SOAP.getNameSpace(con.WDSLCache[queryURL]),
                        action = ((namespace.lastIndexOf("/") != namespace.length - 1) ? namespace + "/" : namespace) + (queryArgs.methodName || "");
                    rMap.header["SOAPAction"] = action;
                    break;
            }
            switch (requestType) {
                case "FORM":
                    // ensure object
                    queryArgs = typeof queryArgs == 'string' ? xui.unserialize(queryArgs) : queryArgs;
                    break;
                case "JSON":
                    rMap.reqType = "json";

                    if (prop.queryMethod == "auto")
                        rMap.method = "POST";
                    // ensure string
                    queryArgs = typeof queryArgs == 'string' ? queryArgs : xui.serialize(queryArgs);
                    break;
                case "XML":
                    rMap.reqType = "xml";
                    proxyType = "ajax";
                    rMap.method = "POST";
                    if (queryUserName && queryPassword) {
                        rMap.username = queryUserName;
                        rMap.password = queryPassword;
                        rMap.header["Authorization"] = "Basic " + con._toBase64(queryUserName + ":" + queryPassword);
                    }
                    // ensure string
                    queryArgs = typeof queryArgs == 'string' ? queryArgs : xui.XMLRPC.wrapRequest(queryArgs);
                    break;
                case "SOAP":
                    rMap.reqType = "xml";
                    proxyType = "ajax";
                    rMap.method = "POST";
                    if (queryUserName && queryPassword) {
                        rMap.username = queryUserName;
                        rMap.password = queryPassword;
                        rMap.header["Authorization"] = "Basic " + con._toBase64(queryUserName + ":" + queryPassword);
                    }
                    // ensure string
                    queryArgs = typeof queryArgs == 'string' ? queryArgs : xui.SOAP.wrapRequest(queryArgs, con.WDSLCache[queryURL]);
                    break;
            }
            if (oAuth2Token)
                rMap.header["Authorization"] = "Bearer " + oAuth2Token;

            // Ajax/JSONP/XDMI
            if (proxyType != "ajax")
                rMap.asy = true;
            if (proxyType == "jsonp")
                rMap.method = "GET";

            options = options || {};
            if (!("asy" in options))
                options.asy = !!prop.queryAsync;
            if (!("method" in options) && prop.queryMethod != "auto")
                options.method = prop.queryMethod;
            if (!("onEnd" in options))
                options.onEnd = onEnd;
            if (!("onStart" in options))
                options.onStart = onStart;

            xui.merge(options, queryOptions);

            xui.merge(options, rMap, 'all');
            options.proxyType = proxyType;

            if (xui.isEmpty(options.header)) {
                delete options.header;
            }
            var cookies = {}, t;
            if (!xui.isEmpty(prop.fakeCookies)) {
                options.$onStart = function () {
                    xui.each(prop.fakeCookies, function (v, k) {
                        if (xui.isSet(t = xui.Cookies.get(k))) {
                            cookies[k] = t;
                            xui.Cookies.remove(k);
                        }
                    });
                    xui.Cookies.set(prop.fakeCookies, 1, "/");
                }
            }
            if (!xui.isEmpty(prop.fakeCookies)) {
                options.$onEnd = function () {
                    xui.each(prop.fakeCookies, function (v, k) {
                        xui.Cookies.remove(k);
                    });
                    xui.Cookies.set(cookies);
                };
            }
            var ajax = xui._getrpc(queryURL, queryArgs, options).apply(null, [queryURL, queryArgs, function (rspData) {
                    var mapb, t;
                    // ensure to json
                    if ((responseType == "XML" || responseType == "SOAP") && !xui.isHash(rspData)) {
                        if (xui.isStr(rspData))
                            rspData = xui.XML.parseXML(rspData);
                        if (responseType == "XML")
                            rspData = xui.XMLRPC.parseResponse(rspData);
                        else if (responseType == "SOAP")
                            rspData = xui.SOAP.parseResponse(rspData, queryArgs.methodName, con.WDSLCache[queryURL]);
                    }
                    // Normally, Gives a change to modify the "rspData"
                    if (prf.afterInvoke) {
                        mapb = prf.boxing().afterInvoke(prf, rspData, requestId);
                        if (xui.isSet(mapb)) rspData = mapb;
                        mapb = null;
                    }

                    // the global handler
                    if (xui.isFun(t2) && false === t2(rspData, requestId, prf)) {
                        return false;
                    } else if (xui.isHash(t2) && xui.isArr(t2.actions)
                        && false === xui.pseudocode._callFunctions(t2, [rspData, requestId, prf], ns.getHost(), null, null, '$APICaller:beforeData')
                    ) {
                        return false;
                    }
                    if (prf.beforeData && false === prf.boxing().beforeData(prf, rspData, requestId)) {
                        return false;
                    }
                    //
                    // try {
                    //     if (rspData.requestStatus == -1 && rspData.errdes) {
                    //         xui.message(rspData.errdes, "服务器出错了！");
                    //     }
                    // } catch (e) {
                    //     xui.message(rspData.errdes, "服务器出错了！");
                    // }


                    if (responseDataTarget && responseDataTarget.length && rspData.requestStatus != -1) {
                        xui.arr.each(responseDataTarget, function (o) {
                                var data = o.path ? xui.get(rspData, o.path.split('.')) : rspData, ids = rspData.ids,
                                    ctx = rspData.ctx, t,
                                    funs = rspData.funs;


                                if (prf.getModule() && ctx && xui.isHash(ctx)) {
                                    var pagectx = prf.getModule().getCtxComponents();
                                    if (pagectx && pagectx.boxing) {
                                        pagectx.boxing().setFormValues(ctx);
                                    }
                                }
                                ;
                                switch (o.type) {
                                    case "alert":
                                        data = xui.stringify(data);
                                        if (xui.Coder) data = xui.Coder.formatText(data);
                                        alert(data);
                                        break;
                                    case "log":
                                        xui.log(data);
                                    case "treegrid":
                                        if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.TreeGrid'] /*&& t.getRootNode()*/) {
                                            t.removeAllRows();
                                            t.insertRows(data);
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && ct.Class['xui.UI.TreeGrid']) {
                                                ct.removeAllRows();
                                                ct.insertRows(data);
                                            }
                                        }
                                        break;

                                    case "grid":  //兼容处理treegrid
                                        if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.TreeGrid'] /*&& t.getRootNode()*/) {
                                            t.removeAllRows();
                                            t.insertRows(data);
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && ct.Class['xui.UI.TreeGrid']) {
                                                ct.removeAllRows();
                                                ct.insertRows(data);
                                            }
                                        }
                                        break;
                                    case "pagebar":
                                        if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.PageBar'] /*&& t.getRootNode()*/) {
                                            t.setTotalCount(data);
                                            t.setEvents("onPageSet", function (profile, page, start, count, eventType, opage, ostart) {
                                                nns.invoke();
                                            });
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && ct.Class['xui.UI.PageBar']) {
                                                ct.setTotalCount(data);
                                                ct.setEvents("onPageSet", function (profile, page, start, count, eventType, opage, ostart) {
                                                    nns.invoke();
                                                });
                                            }
                                        }
                                        break;
                                    case "treeview":
                                        if ((t = xui.get(prf, ["host", o.name])) && (t.Class['xui.UI.TreeView'] || t.Class['xui.UI.TreeBar']) /*&& t.getRootNode()*/) {
                                            t.clearItems();
                                            t.setItems(data);
                                            if (ids && xui.isArr(ids)) {
                                                if (!t.getProperties('selMode') || t.getProperties('selMode') == 'none' || t.getProperties('selMode') == 'single') {
                                                    t.fireItemClickEvent(ids[0])
                                                } else {
                                                    t.setValue(ids.join(t.getProperties('valueSeparator')));
                                                }
                                            } else if (data && data.length > 0 && t.getProperties('selMode') && !t.getProperties('selMode') == 'none' && !t.getProperties('selMode') == 'single') {

                                                t.fireItemClickEvent(data[0].id)
                                            }

                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && (ct.Class['xui.UI.TreeView'] || ct.Class['xui.UI.TreeBar'])) {
                                                ct.clearItems();
                                                ct.setItems(data);
                                                if (!ct.getProperties('selMode') || ct.getProperties('selMode') == 'none' || ct.getProperties('selMode') == 'single') {
                                                    if (ids && xui.isArr(ids)) {
                                                        ct.fireItemClickEvent(ids[0])
                                                    } else {
                                                        ct.setValue(ids.join(t.getProperties('valueSeparator')));
                                                    }
                                                } else if (data.length > 0 && ct.getProperties('selMode') && !ct.getProperties('selMode') == 'none' && !ct.getProperties('selMode') == 'single') {
                                                    ct.fireItemClickEvent(data[0].id)
                                                }
                                            }
                                        }
                                        break;

                                    case "tabs":
                                        var target;
                                        if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.Tabs']) {
                                            target = t;
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if ((ct && t.Class['xui.UI.Tabs'])) {
                                                target = ct;
                                            }
                                        }
                                        if (target) {
                                            target.clearItems();
                                            target.setItems(data);


                                            if (ids && xui.isArr(ids)) {
                                                target.fireItemClickEvent(ids[0])
                                            } else if (data.length > 0) {
                                                target.fireItemClickEvent(data[0].id)
                                            }
                                        }
                                        break;

                                    case "tree"://兼容处理treeview
                                        if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.TreeView'] /*&& t.getRootNode()*/) {
                                            t.clearItems();
                                            t.setItems(data);
                                            if (ids && xui.isArr(ids)) {
                                                t.setValue(data[data.length - 1]);
                                                t.fireItemClickEvent(ids[0])
                                            }
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && ct.Class['xui.UI.TreeView']) {
                                                ct.clearItems();
                                                ct.setItems(data);
                                                if (ids && xui.isArr(ids)) {
                                                    ct.setValue(data[data.length - 1]);
                                                    ct.fireItemClickEvent(ids[0])
                                                }
                                            }
                                        }
                                        break;


                                    case "gallery":
                                        if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.Gallery'] /*&& t.getRootNode()*/) {
                                            t.clearItems();
                                            t.setItems(data);
                                            if (ids && xui.isArr(ids)) {
                                                t.setValue(data[data.length - 1]);
                                                t.fireItemClickEvent(ids[0])
                                            }
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && ct.Class['xui.UI.Gallery']) {
                                                ct.clearItems();
                                                if (ids && xui.isArr(ids)) {
                                                    ct.setValue(data[data.length - 1]);
                                                    ct.fireItemClickEvent(ids[0])
                                                }
                                                ct.setItems(data);
                                            }
                                        }
                                        break;
                                    case "svgpaper":
                                        if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.UI.SVGPaper'] /*&& t.getRootNode()*/) {
                                            t.clearItems();
                                            t.setChildren(data);
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && ct.Class['xui.UI.SVGPaper']) {
                                                ct.clearItems();
                                                ct.setChildren(data);
                                            }
                                        }
                                        break;


                                    case "popmenu":
                                        var pageHost = prf.host;
                                        if (!pageHost.ViewMenuBar) {
                                            pageHost.ViewMenuBar = {};
                                        }
                                        if (pageHost.ViewMenuBar[data.id]) {
                                            pageHost.ViewMenuBar[data.id].destroy();
                                        }
                                        if (data.apis) {
                                            xui.each(data.apis, function (citem) {
                                                xui.create(citem.key)
                                                    .setAlias(citem.alias)
                                                    .setHost(pageHost, citem.alias)
                                                    .setEvents(xui.checkEvents(citem.events))
                                                    .setProperties(citem.properties);
                                            });
                                        }
                                        viewbar = xui.create(data.key)
                                            .setAlias(data.alias)
                                            .setHost(pageHost, data.alias)
                                            .setEvents(xui.checkEvents(data.events))
                                            .setProperties(data.properties);
                                        //  .setTagVar(data.tagVar)
                                        if (data.tagVar) {
                                            viewbar.setTagVar(data.tagVar);
                                        }
                                        if (data.pos && data.pos.src) {
                                            viewbar.pop(data.pos.src);
                                        } else {
                                            viewbar.pop(data.pos);
                                        }
                                        pageHost.ViewMenuBar[data.id] = viewbar;
                                        break;

                                    case
                                    "component"
                                    :
                                        if ((t = xui.get(prf, ["host", o.name])) && (t.Class['xui.UI.Block'] || t.Class['xui.UI.Dialog'])/*&& t.getRootNode()*/) {
                                            t.setChildren(data);
                                            if (t.getModule().afterAppend) {
                                                t.getModule().afterAppend();
                                            }
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && (ct.Class['xui.UI.Block'] || ct.Class['xui.UI.Dialog'])) {
                                                ct.setChildren(data);
                                            }
                                        }
                                        break;
                                    case
                                    "expression"
                                    :
                                        var map = {};
                                        xui.each(data, function (o) {
                                            map[o.alias] = o.properties;
                                        });
                                        if (t = xui.get(prf, ["host", o.name])) {
                                            t.getModule().setData(map);
                                        } else {
                                            prf.getModule().setData(map);
                                        }
                                        break;

                                    case
                                    "spa":
                                        if (SPA) {
                                            xui.each(data, function (o) {
                                                SPA._updateComponent(o);
                                            });
                                        }
                                        break;
                                    case
                                    "databinder"
                                    :
                                        if (t = xui.DataBinder.getFromName(o.name)) {
                                            t.setData(data);
                                            t.updateDataToUI();
                                        }
                                        break;
                                    case
                                    "form"
                                    :
                                        if ((t = xui.get(prf, ["host", o.name])) && t.Class['xui.absContainer'] /*&& t.getRootNode()*/) {
                                            t.setFormValues(data);
                                            t.checkValid(true);
                                        } else if (prf.getModule()) {
                                            var module = prf.getModule(), ct = module.getChildByName(o.name);
                                            if (ct && ct.Class['xui.UI.absContainer']) {
                                                ct.setFormValues(data);
                                                t.checkValid(true);
                                            }
                                        }

                                        break;
                                }
                            }
                        );
                    }
                    if (responseCallback && responseCallback.length) {
                        xui.arr.each(responseCallback, function (o) {
                            var t, host;
                            switch (o.type) {
                                case "host":
                                    if ((t = ns.getHost()) && (t = t.functions) && (t = t[o.name])) {
                                        host = ns.getHost();
                                    }
                                    break;
                                default:
                                    if ((t = xui.$cache.functions[o.name])) {
                                        host = null;
                                    }
                                    break;
                            }
                            if (t && t.actions && xui.isArr(t.actions)) {
                                xui.pseudocode._callFunctions(t, [rspData, ns], host, null, null, (host && host.alias) + "." + ns.alias + "." + o.name);
                            }
                        });
                    }

                    if (rspData && rspData.requestStatus) {
                        if (rspData.requestStatus == -1) {
                            if (prf.onExecuteError) prf.boxing().onExecuteError(prf, rspData, requestId);
                        } else {
                            if (prf.onExecuteSuccess) prf.boxing().onExecuteSuccess(prf, rspData, requestId);
                        }
                    }

                    if (prf.onData) prf.boxing().onData(prf, rspData, requestId);
                    xui.tryF(onSuccess, arguments, this);

                },

                    function (rspData) {
                        if (prf.afterInvoke) prf.boxing().afterInvoke(prf, rspData, requestId);

                        if (responseDataTarget && responseDataTarget.length) {
                            xui.arr.each(responseDataTarget, function (o, t) {
                                switch (o.type) {
                                    case "alert":
                                        rspData = xui.stringify(rspData);
                                        if (xui.Coder) rspData = xui.Coder.formatText(rspData);
                                        alert(rspData);
                                        break;
                                    case "log":
                                        xui.log(rspData);
                                        break;
                                }
                            });
                        }

                        // the global handler
                        if (xui.isFun(t3)) t3(rspData, requestId, prf);
                        else if (xui.isHash(t3) && xui.isArr(t3.actions)) xui.pseudocode._callFunctions(t3, [rspData, requestId, prf], ns.getHost(), null, null, '$APICaller:onError');

                        if (prf.onError) prf.boxing().onError(prf, rspData, requestId);
                        xui.tryF(onFail, arguments, this);
                    }

                    ,
                    threadid, options
                ])
            ;

            if (mode == "quiet")
                ajax.start();
            else if (mode == "return")
                return ajax;
            else
                xui.observableRun(function (threadid) {
                    ajax.threadid = threadid;
                    ajax.start();
                });
        }
    },
    Static: {
        WDSLCache: {}
        ,
        $nameTag: "api_",
        _pool:
            {}
        ,
        _objectProp: {
            tagVar: 1,
            propBinder:
                1,
            queryArgs:
                1,
            queryHeader:
                1,
            queryOptions:
                1,
            fakeCookies:
                1,
            requestDataSource:
                1,
            responseDataTarget:
                1,
            responseCallback:
                1
        }
        ,
        destroyAll: function () {
            this.pack(xui.toArr(this._pool, false), false).destroy();
            this._pool = {};
        }
        ,
        getFromName: function (name) {
            var o = this._pool[name];
            return o && o.boxing();
        }
        ,
        _toBase64: function (str) {
            var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
                arr = [],
                i = 0,
                c1, c2, c3, e1, e2, e3, e4;
            do {
                c1 = str.charCodeAt(i++);
                c2 = str.charCodeAt(i++);
                c3 = str.charCodeAt(i++);
                e1 = c1 >> 2;
                e2 = ((c1 & 3) << 4) | (c2 >> 4);
                e3 = ((c2 & 15) << 2) | (c3 >> 6);
                e4 = c3 & 63;
                if (isNaN(c2)) e3 = e4 = 64;
                else if (isNaN(c3)) e4 = 64;
                arr.push(keyStr.charAt(e1) + keyStr.charAt(e2) + keyStr.charAt(e3) + keyStr.charAt(e4));
            } while (i < str.length);
            return arr.join('');
        }
        ,
        _beforeSerialized: xui.Timer._beforeSerialized,
        DataModel:
            {
                dataBinder: null,
                dataField:
                    null,
                requestId:
                    "",
                queryAsync:
                    true,
                autoRun:
                    false,
                isAllform:
                    false,
                queryURL:
                    "",
                avoidCache:
                    true,
                oAuth2Token:
                    "",
                queryUserName:
                    "",
                queryPassword:
                    "",

                queryMethod:
                    {
                        ini: "auto",
                        listbox:
                            ["auto", "GET", "POST", "PUT", "DELETE"]
                    }
                ,
                requestType: {
                    ini: "FORM",
                    listbox:
                        ["FORM", "JSON", "XML", "SOAP"]
                }
                ,
                responseType: {
                    ini: "JSON",
                    listbox:
                        ["JSON", "TEXT", "XML", "SOAP"]
                }
                ,

                requestDataSource: {
                    ini: []
                }
                ,
                responseDataTarget: {
                    ini: []
                }
                ,
                responseCallback: {
                    ini: []
                }
                ,

                queryArgs: {
                    ini: {}
                }
                ,
                queryHeader: {
                    ini: {}
                }
                ,
                queryOptions: {
                    ini: {}
                }
                ,
                fakeCookies: {
                    ini: {}
                }
                ,
                proxyType: {
                    ini: "auto",
                    listbox:
                        ["auto", "AJAX", "JSONP", "XDMI"]// Cross-Domain Messaging with iframes
                }
                ,
                "name":
                    {
                        set: function (value) {
                            var o = this,
                                ovalue = o.properties.name,
                                c = o.box,
                                _p = c._pool,
                                _old = _p[ovalue],
                                _new = _p[value],
                                ui;

                            //if it exists, overwrite it dir
                            //if(_old && _new)
                            //    throw value+' exists!';

                            _p[o.properties.name = value] = o;

                            //pointer _old the old one
                            if (_new && !_old) o._n = _new._n;
                            //delete the old name from pool
                            if (_old) delete _p[ovalue];
                        }
                    }
                ,
                proxyInvoker: {
                    inner: true,
                    trigger:

                        function () {
                            var prf = this.get(0),
                                prop = prf.properties,
                                bak1 = prop.responseDataTarget,
                                bak2 = prop.responseCallback,
                                fun = function (d) {
                                    prop.responseDataTarget = bak1;
                                    prop.responseCallback = bak2;

                                    d = xui.stringify(d);
                                    if (xui.Coder) d = xui.Coder.formatText(d);
                                    alert(d);
                                };

                            prop.responseDataTarget = [];
                            prop.responseCallback = [];
                            this.invoke(fun, fun);
                        }
                }
            }
        ,
        EventHandlers: {
            beforeInvoke: function (profile, requestId) {
            }
            ,
            afterInvoke: function (profile, rspData, requestId) {
            }
            ,
            onData: function (profile, rspData, requestId) {
            }
            ,

            onExecuteSuccess: function (profile, rspData, requestId) {
            }
            ,

            onExecuteError: function (profile, rspData, requestId) {
            }
            ,

            beforeData: function (profile, rspData, requestId) {
            }
            ,
            onError: function (profile, rspData, requestId) {
            }
        }
    }
})
;